package com.kylin.domain.oauth2.social.wechat.connect;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kylin.domain.oauth2.social.wechat.WechatProperties;
import com.kylin.domain.oauth2.social.wechat.WechatSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * @author Damon S.
 * @description 重写OAuth2Template
 * @date 2019/1/4 0004 10:00
 */
@Slf4j
@Component
public class WechatOAuth2Template {

    /** 微信获取accessToken的url */
    private static final String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token";

    /** 微信刷新token的url */
    private static final String URL_REFRESH_TOKEN = "https://api.weixin.qq.com/sns/oauth2/refresh_token";

    /** 微信获取用户信息的url */
    private static final String URL_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?lang=zh_CN&openid=$openid$";

    /** 微信获取授权码的url */
    private static final String URL_AUTHORIZE = "https://open.weixin.qq.com/connect/qrconnect";

    private static final String URL_CODE2SESSION = "https://api.weixin.qq.com/sns/jscode2session";

    private static final String URL_CODE2SESSION_PARAM = "?js_code=%s&appid=%s&secret=%s&grant_type=%s";

    private static final String URL_ACCESS_TOKEN_PARAM = "?appid=%s&secret=%s&code=%s&grant_type=%s";


    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper mapper = new ObjectMapper();


    /** 根据code获取微信session值 */
    public WechatSession getSession(String code, WechatProperties wxProperties) {
        String sessionUrl = URL_CODE2SESSION +
                String.format(URL_CODE2SESSION_PARAM,
                        code,
                        wxProperties.getAppId(),
                        wxProperties.getAppSecret(),
                        wxProperties.getGrantType()
                );
        String response = restTemplate.getForObject(sessionUrl, String.class);
        log.info("获取微信Session，响应内容: " + response);

        WechatSession wechatSession = WechatSession.EMPTY;
        try {
            wechatSession = mapper.readValue(
                    response,
                    WechatSession.class
            );
        } catch (Exception e) {
            log.error("解析微信Session响应内容失败: " + e);
        }
        return wechatSession;
    }

    /**
     * 获取微信接口调用凭证
     * @return 返回String 可转JSON
     */
    public String getAccessToken(String code, String appId, String appSecret, String grantType){
        String requestUrl = URL_ACCESS_TOKEN +
                String.format(URL_ACCESS_TOKEN_PARAM,
                        appId, appSecret, code, grantType
                );
        String response = restTemplate.getForObject(requestUrl, String.class);
        log.info("获取微信AccessToken，响应内容: " + response);
        return response;
    }

    /**
     * 发送模板消息
     * @param access_token      接口调用凭证
     * @param touser            接收者（用户）的 openid
     * @param template_id       所需下发的模板消息id
     * @param page              点击模版卡片后跳转的页面，仅限本小程序内的页面。支持带参数，（eg：index?foo=bar）。该字段不填则模版无法跳转
     * @param form_id           表单提交场景下，为submit事件带上的formId；支付场景下，为本次支付的 prepay_id
     * @param data              模版内容，不填则下发空模版。具体格式请参照官网示例
     * @param emphasis_keyword  模版需要放大的关键词，不填则默认无放大
     * @return                  返回String可转JSON
     */
//    public String sendTemplateMessage(String access_token, String touser, String template_id, String page, String form_id, Object data, String emphasis_keyword){
//        JSONObject params = new JSONObject();
//        params.put("touser",touser);
//        params.put("template_id",template_id);
//        if (null != page && !"".equals(page)){
//            params.put("page",page);
//        }
//        params.put("form_id",form_id);
//        params.put("data",data);
//        if (null != emphasis_keyword && !"".equals(emphasis_keyword)){
//            params.put("emphasis_keyword",emphasis_keyword);
//        }
//        //发送请求
//        HttpUtil.sendPost(WeChatUrl.SEND_TEMPLATE_MESSAGE.getUrl() + "?access_token=" + access_token, params.toString());
//        String response = restTemplate.postForObject();
//    }

//    @Override
//    protected AccessGrant postForAccessGrant(String accessTokenUrl, MultiValueMap<String, String> parameters) {
//        if ("authorization_code".equals(parameters.getFirst("grant_type"))) {
//            parameters.set("appid", parameters.getFirst("client_id"));
//            parameters.remove("client_id");
//            parameters.set("secret", parameters.getFirst("client_secret"));
//            parameters.remove("client_secret");
//        }
//        return super.postForAccessGrant(accessTokenUrl, parameters);
//    }
//
//    @Override
//    protected WechatAccessGrant createAccessGrant(String accessToken, String scope, String refreshToken, Long expiresIn,
//                                                  Map<String, Object> response) {
//        return new WechatAccessGrant(accessToken, scope, refreshToken, expiresIn, (String) response.get("openid"),
//                (String) response.get("unionid"));
//    }
//
//    @Override
//    public AccessGrant exchangeForAccess(String authorizationCode, String redirectUri,
//                                         MultiValueMap<String, String> parameters) {
//        String accessTokenRequestUrl = URL_ACCESS_TOKEN +
//                "?appid=" + clientId +
//                "&secret=" + clientSecret +
//                "&code=" + authorizationCode +
//                "&grant_type=authorization_code" +
//                "&redirect_uri=" + redirectUri;
//        return getAccessToken(accessTokenRequestUrl);
//    }
//
//    @Override
//    public AccessGrant refreshAccess(String refreshToken,
//                                     MultiValueMap<String, String> additionalParameters) {
//        String refreshTokenUrl = URL_REFRESH_TOKEN +
//                "?appid=" + clientId +
//                "&grant_type=refresh_token" +
//                "&refresh_token=" + refreshToken;
//        return getAccessToken(refreshTokenUrl);
//    }
//
//    @SuppressWarnings("unchecked")
//    private AccessGrant getAccessToken(String accessTokenRequestUrl) {
//        log.info("获取access_token, 请求URL: " + accessTokenRequestUrl);
//
//        //发送获取token
//        String response = restTemplate.getForObject(accessTokenRequestUrl, String.class);
//
//        log.info("获取access_token, 响应内容: " + response);
//
//        Map<String, Object> responseMap = null;
//        try {
//            responseMap = new ObjectMapper().readValue(response, Map.class);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        Object errCode = getString(responseMap, "errcode");
//        //返回错误码时直接返回空
//        if (!StringUtils.isEmpty(errCode)) {
//            Object errMsg = Objects.requireNonNull(responseMap).get("errmsg");
//            throw new RuntimeException("获取access token失败, errcode:" + errCode + ", errmsg:" + errMsg);
//        }
//
//        //获取token的时候，会返回openid，保存
//        return new WechatAccessGrant(
//                getString(responseMap, "access_token"),
//                getString(responseMap, "scope"),
//                getString(responseMap, "refresh_token"),
//                Long.parseLong(Objects.requireNonNull(getString(responseMap, "expires_in"))),
//                getString(responseMap, "openid"),
//                getString(responseMap, "unionid"));
//    }
//
//    private String getString(Map<String, Object> map, Object key) {
//        if (CollectionUtils.isEmpty(map)) {
//            return null;
//        }
//        Object answer = map.get(key);
//        return Objects.isNull(answer) ? null : answer.toString();
//    }
//
//    /**
//     * 构建获取授权码的请求。也就是引导用户跳转到微信的地址。
//     */
//    @Override
//    public String buildAuthenticateUrl(OAuth2Parameters parameters) {
//        return super.buildAuthenticateUrl(parameters) +
//                "&appid=" + clientId + "&scope=snsapi_login";
//    }
//
//    @Override
//    public String buildAuthorizeUrl(OAuth2Parameters parameters) {
//        return buildAuthenticateUrl(parameters);
//    }
//
//    /**
//     * 微信返回的contentType是html/text，添加相应的HttpMessageConverter来处理。
//     */
//    @Override
//    protected RestTemplate createRestTemplate() {
//        RestTemplate restTemplate = super.createRestTemplate();
//        restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
//        return restTemplate;
//    }
}
